#include "PCH.h"
#include "device_dx9.h"
#include "enum_convert_dx9.h"
using namespace Graphic;




Graphic::DeviceDX9::DeviceDX9()
	: m_d3d9(0)
	, m_pDevice(0)
	, m_bIsValid(false)
{
}

bool Graphic::DeviceDX9::Initial(const CreateParam& cp)
{
	if(m_bIsValid)
	{
		return false;
	}
	if(0 == (m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
	{
		return false;
	}

	HWND hWindow = (HWND)cp.WindowHandle;
	InitD3DPP(m_d3dParam);

	if( FAILED(m_d3d9->CreateDevice(
			D3DADAPTER_DEFAULT,
			D3DDEVTYPE_HAL,
			hWindow,
			D3DCREATE_HARDWARE_VERTEXPROCESSING,
			&m_d3dParam,
			&m_pDevice)
		)
	)
	{
		m_bIsValid =  false;
	}
	else
	{
		m_bIsValid = true;
	}
	
	return m_bIsValid;
}

void Graphic::DeviceDX9::InitD3DPP( D3DPRESENT_PARAMETERS& d3dpp )
{

	ZeroMemory(&m_d3dParam, sizeof(m_d3dParam));

	m_d3dParam.Windowed		= true;
	m_d3dParam.SwapEffect	= D3DSWAPEFFECT_DISCARD;
	m_d3dParam.BackBufferFormat = D3DFMT_UNKNOWN;
}



bool Graphic::DeviceDX9::IsValid()
{
	return m_bIsValid;
}

int Graphic::DeviceDX9::GetHandle()
{
	return (int)m_pDevice;
}

void Graphic::DeviceDX9::Release()
{
	if(m_bIsValid)
	{
		m_pDevice->Release();
		m_d3d9->Release();
		m_bIsValid = false;
	}
	delete this;
}

void Graphic::DeviceDX9::Clear(int color, int Buffers, float z, float stencil)
{
/*
Clear will fail if you:
Try to clear either the depth buffer or the stencil buffer of a render target that does not have an attached depth buffer. 
Try to clear the stencil buffer when the depth buffer does not contain stencil data. 
*/
	m_pDevice->Clear(
		0,					//rect count
		0,					//rect array
		CB_To_Clear_DX9(Buffers),	//buffer
		D3DCOLOR(color),	//color
		1.0f,				//z
		0					//stencil
		);
}

void Graphic::DeviceDX9::Present(void* pSrcRect, void*pDstRect, void* hWindow)
{
	m_pDevice->Present(
		(RECT*)pSrcRect,
		(RECT*)pDstRect,
		(HWND)hWindow,
		0			//DirtyRegion
		);
}

bool Graphic::DeviceDX9::Begin()
{
	if( FAILED(m_pDevice->BeginScene()))
	{
		return false;
	}
	return true;
}

void Graphic::DeviceDX9::End()
{
	m_pDevice->EndScene();
}
